import { Select } from 'ol/interaction';
import Draw, { createBox, createRegularPolygon } from 'ol/interaction/Draw';
import { Fill, Stroke, Style, Circle } from 'ol/style';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import Overlay from 'ol/Overlay';
import LineString from 'ol/geom/LineString';
import Point from 'ol/geom/Point';
import Polygon from 'ol/geom/Polygon';
import CirclePolygon from 'ol/geom/Circle';
import { getArea, getLength } from 'ol/sphere';
import { unByKey } from 'ol/Observable';
import { formartLonLat, decimalKeep } from '@/utils';

import store from '@/store';
function Interaction(map) {
    this.map = map;
    this.draw = null;
    this.drawLayer = null;
    this.geometryFunction - null; // 更新几何坐标时调用的函数。
    this.measureTooltipElement = null; //tooltip里面的div
    this.measureTooltip = null; //提示tooltip
    this.geometryCollection = [];
    this.overlayCollection = [];
}

/**
 * description 捕获点击地图的要素
 * @param Layer 容纳要素的图层
 */
Interaction.prototype.addSelect = function (Layers) {
    let selet = new Select({ layers: Layers });
    this.map.addInteraction(selet);
    return selet;
};

Interaction.prototype.initDraw = function (layerName) {
    //------------添加绘制图层
    let drawVectorLayer = new VectorLayer({
        source: new VectorSource(),
        zIndex: 20,
    });
    drawVectorLayer.set('layerName', layerName);
    this.map.addLayer(drawVectorLayer);
    this.drawLayer = drawVectorLayer;
};
//手动绘制预警区
Interaction.prototype.addYjDraw = function (featureType, yjtype) {
    if (featureType == 'Polygon') {
        let geometryFunction;
        if (!this.drawLayer) {
            this.initDraw('绘制图层');
            this.draw = new Draw({
                source: this.drawLayer.getSource(),
                type: featureType,
                geometryFunction: geometryFunction,
                freehand: true, //这个是手绘模式
                //绘制时，在地图上呈现的样式
                style: new Style({
                    fill: new Fill({
                        color: 'rgba(255, 255, 255, 0.2)',
                    }),
                    stroke: new Stroke({
                        color: '#ffcc33',
                        width: 2,
                    }),
                    image: new Circle({
                        radius: 7,
                        fill: new Fill({
                            color: '#ffcc33',
                        }),
                    }),
                }),
            });
        }
        if (yjtype == '3') {
            this.draw = new Draw({
                source: this.drawLayer.getSource(),
                type: featureType,
                geometryFunction: geometryFunction,
                freehand: true, //这个是手绘模式
                //绘制时，在地图上呈现的样式
                style: new Style({
                    fill: new Fill({
                        color: 'rgba(255, 255, 255, 0.2)',
                    }),
                    stroke: new Stroke({
                        color: '#e23e30',
                        width: 2,
                    }),
                    image: new Circle({
                        radius: 7,
                        fill: new Fill({
                            color: '#e23e30',
                        }),
                    }),
                }),
            });
        } else if (yjtype == '2') {
            this.draw = new Draw({
                source: this.drawLayer.getSource(),
                type: featureType,
                geometryFunction: geometryFunction,
                freehand: true, //这个是手绘模式
                //绘制时，在地图上呈现的样式
                style: new Style({
                    fill: new Fill({
                        color: 'rgba(255, 255, 255, 0.2)',
                    }),
                    stroke: new Stroke({
                        color: '#de8615',
                        width: 2,
                    }),
                    image: new Circle({
                        radius: 7,
                        fill: new Fill({
                            color: '#de8615',
                        }),
                    }),
                }),
            });
        } else if (yjtype == '1') {
            this.draw = new Draw({
                source: this.drawLayer.getSource(),
                type: featureType,
                geometryFunction: geometryFunction,
                freehand: true, //这个是手绘模式
                //绘制时，在地图上呈现的样式
                style: new Style({
                    fill: new Fill({
                        color: 'rgba(255, 255, 255, 0.2)',
                    }),
                    stroke: new Stroke({
                        color: '#FFFD03',
                        width: 2,
                    }),
                    image: new Circle({
                        radius: 7,
                        fill: new Fill({
                            color: '#FFFD03',
                        }),
                    }),
                }),
            });
        } else if (yjtype == '0') {
            this.draw = new Draw({
                source: this.drawLayer.getSource(),
                type: featureType,
                geometryFunction: geometryFunction,
                freehand: true, //这个是手绘模式
                //绘制时，在地图上呈现的样式
                style: new Style({
                    fill: new Fill({
                        color: 'rgba(255, 255, 255, 0.2)',
                    }),
                    stroke: new Stroke({
                        color: '#327eef',
                        width: 2,
                    }),
                    image: new Circle({
                        radius: 7,
                        fill: new Fill({
                            color: '#327eef',
                        }),
                    }),
                }),
            });
        }
        this.cancelDraw();
        this.map.addInteraction(this.draw);
        let listener;
        this.createMeasureTooltip();
        let sketch;
        let _this = this;
        this.draw.on('drawstart', function (e) {
            sketch = e.feature; //绘制的要素
            let tooltipCoord = e.coordinate; // 绘制的坐标
            listener = sketch.getGeometry().on('change', function () {
                let geom = e.feature.getGeometry(); //绘制的几何要素
                tooltipCoord = geom.getInteriorPoint().getCoordinates(); //坐标
            });
        });
        this.draw.on('drawend', function (e) {
            let geom = e.feature.getGeometry(); //绘制的几何要素
            if (yjtype == '3') {
                e.feature.setStyle(() => {
                    return new Style({
                        fill: new Fill({
                            color: '#e23e30',
                        }),
                    });
                });
            } else if (yjtype == '2') {
                e.feature.setStyle(() => {
                    return new Style({
                        fill: new Fill({
                            color: '#de8615',
                        }),
                    });
                });
            } else if (yjtype == '1') {
                e.feature.setStyle(() => {
                    return new Style({
                        fill: new Fill({
                            color: '#FFFD03',
                        }),
                    });
                });
            } else if (yjtype == '0') {
                e.feature.setStyle(() => {
                    return new Style({
                        fill: new Fill({
                            color: '#327eef',
                        }),
                    });
                });
            }
            unByKey(listener);
            _this.geometryCollection.push(geom); //添加几何体
            // _this.cancelDraw(); //移除上一次绘制事件
            sketch = null; //置空当前绘制的要素对象
            // 
        });
    }
};
Interaction.prototype.cancelYjDraw = function () {
    this.cancelDraw(); //移除交互
    this.clearPolygon(); //清除图层上的所有要素
    this.geometryCollection = [];
    this.cancelDraw(); //移除上一次绘制事件
    this.draw = null;
};
Interaction.prototype.cleargeometryCollection = function () {
    this.geometryCollection = [];
};
//mode 0 多绘制模式
//mode 1 单绘制模式，只能保留一个几何体
Interaction.prototype.addDraw = function (featureType, mode = 0, node = 1) {
    //如果是单绘制事件，之前的多边形要删除
    if (mode == 1) {
        this.clearPolygon(); //清除图层上的所有要素
        this.geometryCollection = []; //清除geom
    }
    let geometryFunction;
    if (!this.drawLayer) {
        this.initDraw('绘制图层');
        this.draw = new Draw({
            source: this.drawLayer.getSource(),
            type: featureType,
            geometryFunction: geometryFunction,
            // freehand: true,//这个是手绘模式
            //绘制时，在地图上呈现的样式
            style: new Style({
                fill: new Fill({
                    color: 'rgba(255, 255, 255, 0.2)',
                }),
                stroke: new Stroke({
                    color: '#ffcc33',
                    width: 2,
                }),
                image: new Circle({
                    radius: 7,
                    fill: new Fill({
                        color: '#ffcc33',
                    }),
                }),
            }),

        });
    }
    //先清除之前的draw
    this.cancelDraw();
    //
    if (featureType == 'Rectangle') {
        featureType = 'Circle';
        geometryFunction = createBox();
    }
    if (featureType == 'Square') {
        featureType = 'Circle';
        geometryFunction = createRegularPolygon(4);
    }
    this.draw = new Draw({
        source: this.drawLayer.getSource(),
        type: featureType,
        geometryFunction: geometryFunction,
        // freehand: true,//这个是手绘模式
        //绘制时，在地图上呈现的样式
        style: new Style({
            fill: new Fill({
                color: 'rgba(255, 255, 255, 0.2)',
            }),
            stroke: new Stroke({
                color: '#ffcc33',
                width: 2,
            }),
            image: new Circle({
                radius: 7,
                fill: new Fill({
                    color: '#ffcc33',
                }),
            }),
        }),

    });
    this.map.addInteraction(this.draw);
    //先创建一个测量提示框
    this.createMeasureTooltip();
    let listener;
    let sketch;
    let _this = this;
    let pointCount = 0;
    //当绘制开始
    this.draw.on('drawstart', function (e) {
        pointCount = 0;
        sketch = e.feature; //绘制的要素
        let tooltipCoord = e.coordinate; // 绘制的坐标
        this.coordinateTemp = e.feature.getGeometry();
        //绑定change事件，根据绘制几何类型得到测量长度值或面积值，并将其设置到测量工具提示框中显示
        listener = sketch.getGeometry().on('change', function (evt) {
            let geom = evt.target; //绘制几何要素
            let output;
            if (geom instanceof Polygon) {
                output = _this.formatArea(geom); //面积值
                tooltipCoord = geom.getInteriorPoint().getCoordinates(); //坐标
            } else if (geom instanceof LineString) {
                if (node == 1) {
                    output = _this.formatLength(geom); //长度值
                    tooltipCoord = geom.getLastCoordinate(); //坐标

                }
            } else if (geom instanceof CirclePolygon) {
                output = _this.formatCircle(geom); //半径与圆心与面积
                tooltipCoord = geom.getCenter(); //坐标
            }
            _this.measureTooltipElement.innerHTML = output; //将测量值设置到测量工具提示框中显示
            _this.measureTooltip.setPosition(tooltipCoord); //设置测量工具提示框的显示位置
        });
    });
    //限制绘制次数
    if (node == 0) {
        this.map.on('click', function (e) {
            pointCount++;
            if (pointCount == 3) {
                _this.map.removeInteraction(_this.draw);
                _this.cancelDraw(); //移除交互
            }
        });
    };

    //当绘制完成
    this.draw.on('drawend', function (e) {
        ;
        let drawpoint = e.feature.getGeometry().getCoordinates();
        ;
        store.commit('setDrawpoints', drawpoint);
        if (featureType == 'Point') {
            window.functionForpoints(drawpoint);
        }
        // window.functionDrawpoint(drawpoint)
        let geom = e.feature.getGeometry(); //绘制的几何要素

        // , "geom.getCoordinates()");
        if (geom instanceof Point) {
            //绘制点时，drawstart不会触发，所以在drawend中进行测量经纬度
            _this.measureTooltipElement.innerHTML = _this.formatCoor(geom); //将测量值设置到测量工具提示框中显示
            _this.measureTooltip.setPosition(geom.getLastCoordinate()); //设置测量工具提示框的显示位置
        }

        _this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-static'; //设置测量提示框的样式
        let closebtn = document.createElement('span');
        closebtn.className = 'ol-measure-clear';
        closebtn.innerHTML = '×';
        closebtn.onclick = function () {
            _this.drawLayer.getSource().removeFeature(e.feature);
            closebtn.parentNode.parentNode.remove();

            let coors = e.feature.getGeometry().getCoordinates()[0];
            let res = [];
            coors.forEach(item => {
                ;
                res.push({ longitude: item[0], latitude: item[1] });
            });
            ;
        };
        _this.measureTooltipElement.appendChild(closebtn);
        _this.measureTooltip.setOffset([0, -7]);
        // unset sketch
        sketch = null; //置空当前绘制的要素对象
        _this.measureTooltipElement = null; //置空测量工具提示框对象
        _this.createMeasureTooltip(); //重新创建一个测试工具提示框显示结果
        unByKey(listener);
        // if (geom instanceof Point) {
        //     //如果是绘制点，就不清除绘制事件
        //     return
        // }
        _this.geometryCollection.push(geom); //添加几何体
        _this.cancelDraw(); //移除上一次绘制事件
        _this.draw = null;
    });
};
//mode 0 多绘制模式
//mode 1 单绘制模式，只能保留一个几何体
Interaction.prototype.addAreaDraw = function (featureType, mode = 0) {
    //如果是单绘制事件，之前的多边形要删除
    if (mode == 1) {
        this.clearPolygon(); //清除图层上的所有要素
        this.geometryCollection = []; //清除geom
    }
    let geometryFunction;
    if (!this.drawLayer) {
        this.initDraw('绘制图层');
        this.draw = new Draw({
            source: this.drawLayer.getSource(),
            type: featureType,
            geometryFunction: geometryFunction,
            // freehand: true,//这个是手绘模式
            //绘制时，在地图上呈现的样式
            style: new Style({
                fill: new Fill({
                    color: 'rgba(255, 255, 255, 0.2)',
                }),
                stroke: new Stroke({
                    color: '#ffcc33',
                    width: 2,
                }),
                image: new Circle({
                    radius: 7,
                    fill: new Fill({
                        color: '#ffcc33',
                    }),
                }),
            }),
        });
    }
    //先清除之前的draw
    this.cancelDraw();
    //
    if (featureType == 'Rectangle') {
        featureType = 'Circle';
        geometryFunction = createBox();
    }
    if (featureType == 'Square') {
        featureType = 'Circle';
        geometryFunction = createRegularPolygon(4);
    }
    this.draw = new Draw({
        source: this.drawLayer.getSource(),
        type: featureType,
        geometryFunction: geometryFunction,
        // freehand: true,//这个是手绘模式
        //绘制时，在地图上呈现的样式
        style: new Style({
            fill: new Fill({
                color: 'rgba(255, 255, 255, 0.2)',
            }),
            stroke: new Stroke({
                color: '#ffcc33',
                width: 2,
            }),
            image: new Circle({
                radius: 7,
                fill: new Fill({
                    color: '#ffcc33',
                }),
            }),
        }),
    });
    this.map.addInteraction(this.draw);
    let listener;
    this.createMeasureTooltip();
    let sketch;
    let _this = this;
    this.draw.on('drawstart', function (e) {
        sketch = e.feature; //绘制的要素
        let tooltipCoord = e.coordinate; // 绘制的坐标
        listener = sketch.getGeometry().on('change', function () {
            let geom = e.feature.getGeometry(); //绘制的几何要素
            tooltipCoord = geom.getInteriorPoint().getCoordinates(); //坐标
        });
    });
    this.draw.on('drawend', function (e) {
        let geom = e.feature.getGeometry(); //绘制的几何要素
        unByKey(listener);
        _this.geometryCollection.push(geom); //添加几何体
        _this.cancelDraw(); //移除上一次绘制事件
        sketch = null; //置空当前绘制的要素对象
        store.commit("setGeom", geom)
    });
};
Interaction.prototype.addNewAreaDraw = function (featureType, mode = 0) {
    //如果是单绘制事件，之前的多边形要删除
    if (mode == 1) {
        this.clearPolygon(); //清除图层上的所有要素
        this.geometryCollection = []; //清除geom
    }
    let geometryFunction;
    let isCircleFlag = false;
    if (featureType == 'Rectangle') {
        featureType = 'Circle';
        geometryFunction = createBox();
    }
    else if (featureType == 'Square') {
        featureType = 'Circle';
        geometryFunction = createRegularPolygon(4);
    } else if (featureType == 'Circle') {
        isCircleFlag = true;
    }
    if (!this.drawLayer) {
        this.initDraw('绘制图层');
        this.draw = new Draw({
            source: this.drawLayer.getSource(),
            type: featureType,
            geometryFunction: geometryFunction,
            // freehand: true,//这个是手绘模式
            //绘制时，在地图上呈现的样式
            style: new Style({
                fill: new Fill({
                    color: 'rgba(255, 255, 255, 0.2)',
                }),
                stroke: new Stroke({
                    color: '#ffcc33',
                    width: 2,
                }),
                image: new Circle({
                    radius: 7,
                    fill: new Fill({
                        color: '#ffcc33',
                    }),
                }),
            }),
        });
    }
    //先清除之前的draw
    this.cancelDraw();
    this.draw = new Draw({
        source: this.drawLayer.getSource(),
        type: featureType,
        geometryFunction: geometryFunction,
        // freehand: true,//这个是手绘模式
        //绘制时，在地图上呈现的样式
        style: new Style({
            fill: new Fill({
                color: 'rgba(255, 255, 255, 0.2)',
            }),
            stroke: new Stroke({
                color: '#ffcc33',
                width: 2,
            }),
            image: new Circle({
                radius: 7,
                fill: new Fill({
                    color: '#ffcc33',
                }),
            }),
        }),
    });
    this.map.addInteraction(this.draw);
    let listener;
    this.createMeasureTooltip();
    let sketch;
    let _this = this;
    this.draw.on('drawstart', function (e) {
        sketch = e.feature; //绘制的要素
        let tooltipCoord = e.coordinate; // 绘制的坐标
        listener = sketch.getGeometry().on('change', function () {
            let geom = e.feature.getGeometry(); //绘制的几何要素
            ;
            if (isCircleFlag) {
                tooltipCoord = geom.getCenter(); //坐标
            } else {
                tooltipCoord = geom.getInteriorPoint().getCoordinates(); //坐标
            }

        });
    });
    this.draw.on('drawend', function (e) {
        let geom = e.feature.getGeometry(); //绘制的几何要素
        unByKey(listener);
        _this.geometryCollection.push(geom); //添加几何体
        _this.cancelDraw(); //移除上一次绘制事件
        sketch = null; //置空当前绘制的要素对象
        // 
        if (isCircleFlag) {
            let center = geom.getCenter(); // [centerX, centerY]
            let radius = geom.getRadius();

            // 计算正方形的边长
            let sideLength = 2 * radius / Math.sqrt(2);

            // 计算正方形的四个顶点坐标
            let topLeft = [center[0] - sideLength / 2, center[1] + sideLength / 2];
            let topRight = [center[0] + sideLength / 2, center[1] + sideLength / 2];
            let bottomLeft = [center[0] - sideLength / 2, center[1] - sideLength / 2];
            let bottomRight = [center[0] + sideLength / 2, center[1] - sideLength / 2];
            let extent = [topLeft, topRight, bottomRight, bottomLeft];
            store.commit("setCircle", extent)
        } else {
            store.commit("setArea", geom)
        }
    });
};
//清除绘制，包括绘制的几何图形
Interaction.prototype.clearDraw = function () {
    this.draw && this.cancelDraw(); //移除交互
    this.clearPolygon(); //清除图层上的所有要素
    this.geometryCollection = [];
};

//清除图层上的所有要素
Interaction.prototype.clearPolygon = function () {
    this.drawLayer && this.drawLayer.getSource().clear(); //清除图层上的所有要素
    // ;
    this.overlayCollection.forEach(item => {
        this.map.removeOverlay(item);
    });
};

//撤销
Interaction.prototype.removeLastPoint = function () {
    this.draw && this.draw.removeLastPoint();
};

//取消
Interaction.prototype.cancelDraw = function () {
    this.map.removeInteraction(this.draw);
};

Interaction.prototype.getGeometryCollection = function () {
    return this.geometryCollection;
};

/**
 *创建一个新的测量工具提示框（tooltip）
 */
Interaction.prototype.createMeasureTooltip = function () {
    if (this.measureTooltipElement) {
        this.measureTooltipElement.parentNode.removeChild(this.measureTooltipElement);
    }
    this.measureTooltipElement = document.createElement('div');
    this.measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
    this.measureTooltip = new Overlay({
        element: this.measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center',
    });
    this.measureTooltip.type = '绘制overlay';
    this.map.addOverlay(this.measureTooltip);
    this.overlayCollection.push(this.measureTooltip);
};

/**
 * 测量长度输出
 * @param {ol.geom.LineString} line
 * @return {string}
 */
Interaction.prototype.formatLength = function (line) {
    let sourceProj = this.map.getView().getProjection(); //获取投影坐标系
    let length = getLength(line, { projection: sourceProj });
    let output;
    if (length > 100) {
        output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km';
    } else {
        output = Math.round(length * 100) / 100 + ' ' + 'm';
    }
    return output;
};

/**
 * 测量面积输出,如果是矩形，就测量长宽
 * @param {ol.geom.Polygon} polygon
 * @return {string}
 */
Interaction.prototype.formatArea = function (polygon) {
    let sourceProj = this.map.getView().getProjection(); //获取投影坐标系
    let area = getArea(polygon, { projection: sourceProj });
    let output;
    if (area > 10000) {
        output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>';
    } else {
        output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>';
    }
    return output;
};

/**
 * 测量面积半径圆心输出
 * @param {ol.geom.Polygon} polygon
 * @return {string}
 */
Interaction.prototype.formatCircle = function (polygon) {
    let sourceProj = this.map.getView().getProjection(); //获取投影坐标系
    let centerLogLat = formartLonLat(polygon.getCenter(), 2);
    let radius = decimalKeep(polygon.getRadius() * sourceProj.getMetersPerUnit(), 2);
    let area = decimalKeep(Math.PI * Math.pow(radius, 2), 2);
    let outputArea;
    if (area > 10000) {
        outputArea = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>';
    } else {
        outputArea = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>';
    }
    if (radius > 1000) {
        radius = Math.round((radius / 1000) * 100) / 100 + ' ' + 'km<sup>2</sup>';
    } else {
        radius = Math.round(radius * 100) / 100 + ' ' + 'm<sup>2</sup>';
    }
    let output = `
    <div>圆心:${centerLogLat[0]},${centerLogLat[1]}</div>
    <div>半径:${radius}</div>
    <div>面积:${outputArea}</div>
    `;
    return output;
};

/**
 * 判断是否是矩形，并且判断是否是方形
 * @param {ol.geom.Polygon} polygon
 * @return {string}
 */
Interaction.prototype.polygonType = function (polygon) {
    let coors = polygon.getCoordinates()[0];
    function isRectangle(coors) {
        //如果有五个坐标，并且第一个坐标与最后一个坐标相等
        if (
            coors &&
            coors.length == 5 &&
            coors[0][0] == coors[coors.length - 1][0] &&
            coors[0][1] == coors[coors.length - 1][1]
        ) {
            if (
                coors[0][1] == coors[1][1] &&
                coors[1][0] == coors[2][0] &&
                coors[2][1] == coors[3][1] &&
                coors[3][0] == coors[4][0]
            ) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    //已经通过矩形判断的情况下,长等于宽
    function isSquare(coors) {
        let c = coors[0][0] - coors[1][0];
        let k = coors[1][1] - coors[2][1];
        if (c == k) {
            return true;
        } else {
            return false;
        }
    }
    //判断是否是多边形
    if (polygon && polygon instanceof Polygon) {
        //判断是否是矩形
        if (isRectangle(coors)) {
            //判断是否是方形
            if (isSquare(coors)) {
                return 'square';
            } else {
                return 'rectangle';
            }
        } else {
            return 'polygon';
        }
    } else {
        return 'none';
    }
};

/**
 * 测量坐标值输出
 * @param {ol.geom.Polygon} polygon
 * @return {string}
 */
Interaction.prototype.formatCoor = function (point) {
    let output;
    let coor = point.getCoordinates();
    if (coor) {
        let lonlat = formartLonLat(coor, 2);
        output = `<div>经度:${lonlat[0]}</div><div>纬度:${lonlat[1]}</div>`;
    }
    return output;
};

export default Interaction;
